#include "nvds_custom_meta.h"

NVDSCustomMeta::NVDSCustomMeta() : m_imgSize(0, 0)
{
}

NVDSCustomMeta::~NVDSCustomMeta()
{
}

NvDsMetaType NVDSCustomMeta::getType()
{
    static const gchar USER_FRAME_META_TYPENAME[] = "NVIDIA.PIPELINE.CUSTOM_META";
    return nvds_get_user_meta_type((char *)USER_FRAME_META_TYPENAME);
}

gpointer NVDSCustomMeta::gstCopy(gpointer data, gpointer user_data)
{
    NVDSCustomMeta *src_user_metadata = static_cast<NVDSCustomMeta *>(data);
    NVDSCustomMeta *dst_user_metadata = new NVDSCustomMeta();
    if (src_user_metadata->m_imgBuffer.size() > 0)
        dst_user_metadata->m_imgBuffer = std::move(src_user_metadata->m_imgBuffer);
    dst_user_metadata->m_imgSize   = src_user_metadata->m_imgSize;
    dst_user_metadata->m_timestamp = src_user_metadata->m_timestamp;
    return static_cast<gpointer>(dst_user_metadata);
}

void NVDSCustomMeta::gstRelease(gpointer data, gpointer user_data)
{
    if (data) {
        delete (NVDSCustomMeta *)data;
    }
}

gpointer NVDSCustomMeta::gstToNvdsTransform(gpointer data, gpointer user_data)
{
    NvDsUserMeta   *user_meta         = static_cast<NvDsUserMeta *>(data);
    NVDSCustomMeta *src_user_metadata = (NVDSCustomMeta *)user_meta->user_meta_data;
    NVDSCustomMeta *dst_user_metadata = (NVDSCustomMeta *)gstCopy(src_user_metadata, nullptr);
    return static_cast<gpointer>(dst_user_metadata);
}

gpointer NVDSCustomMeta::nvdsCopy(gpointer data, gpointer user_data)
{
    NvDsUserMeta   *user_meta         = static_cast<NvDsUserMeta *>(data);
    NVDSCustomMeta *src_user_metadata = (NVDSCustomMeta *)user_meta->user_meta_data;
    NVDSCustomMeta *dst_user_metadata = new NVDSCustomMeta();
    if (src_user_metadata->m_imgBuffer.size() > 0)
        dst_user_metadata->m_imgBuffer = std::move(src_user_metadata->m_imgBuffer);
    dst_user_metadata->m_imgSize   = src_user_metadata->m_imgSize;
    dst_user_metadata->m_timestamp = src_user_metadata->m_timestamp;
    return static_cast<gpointer>(dst_user_metadata);
}

void NVDSCustomMeta::nvdsRelease(gpointer data, gpointer user_data)
{
    NvDsUserMeta   *user_meta     = static_cast<NvDsUserMeta *>(data);
    NVDSCustomMeta *user_metadata = (NVDSCustomMeta *)user_meta->user_meta_data;
    gstRelease(user_metadata, nullptr);
}

void NVDSCustomMeta::gstBufferAddMeta(GstBuffer *buf)
{
    static const gchar USER_FRAME_META_TYPENAME[] = "NVIDIA.PIPELINE.CUSTOM_META";
    NvDsMeta          *meta                       = gst_buffer_add_nvds_meta(buf, this, NULL, gstCopy, gstRelease);
    meta->meta_type                               = (GstNvDsMetaType)NVDSCustomMeta::getType();
    meta->gst_to_nvds_meta_transform_func         = gstToNvdsTransform;
    meta->gst_to_nvds_meta_release_func           = nvdsRelease;
}